/*
*	Created:			06.03.10
*	Author:				009
*	Last Modifed:		-
*/

// SDK
#include "SDK/amx/amx.h"
#include "SDK/plugincommon.h"
// core
#include "math.h"
#include <malloc.h>
// plugin
#include "os.h"
#include "main.h"
// npc core
#include "NPC class.h"
// nodes
#include "Nodes.h"
// zmap
#include "ZMap.h"
// samp data
#include "samp defines.h"
#include "samp address.h"
#include "samp structs.h"

extern	CNPC*	NPC[MAX_NPCS];

extern	CNode*	Nodes[MAX_NODES];

extern	CZMap*	ZMap;

extern	float	WeaponsDamage[MAX_WEAPONS + 1];
extern	int		WeaponsReloadTime[MAX_WEAPONS + 1];
extern	int		VisualDeath;

extern DWORD	LoggingJoinPointer;
extern DWORD	LoggingPartPointer;

extern DWORD	CPlayerInCarSyncOffset;

float Roll2Grad(float roll);
float Grad2Roll(float grad);


// main vars
extern DWORD	c_samp;
extern DWORD	c_players;
extern DWORD	c_vehicles;
extern DWORD	CSampPointer;

// CreateNPC(NPC:npcid,npcname[]);
static cell AMX_NATIVE_CALL n_CreateNPC( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	char* temp;
	amx_StrParam(amx, params[2], temp);
	if(!NPC[npcid])
	{
		NPC[npcid] = new CNPC(npcid,temp);
		return 1;
	}
	return 0;
}

// DestroyNPC(NPC:npcid);
static cell AMX_NATIVE_CALL n_DestroyNPC( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		delete NPC[npcid];
		NPC[npcid] = 0;
		return 1;
	}
	return 0;
}
// IsValidNPC(NPC:npcid);
static cell AMX_NATIVE_CALL n_IsValidNPC( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid]) return 1;
	return 0;
}
// GetNPCState(NPC:npcid);
static cell AMX_NATIVE_CALL n_GetNPCState( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid]) return NPC[npcid]->state;
	return 0;
}
// SetNPCPos(NPC:npcid,Float:X,Float:Y,Float:Z);
static cell AMX_NATIVE_CALL n_SetNPCPos( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x = amx_ctof(params[2]);
		float y = amx_ctof(params[3]);
		float z = amx_ctof(params[4]);
		NPC[npcid]->SetPos(x,y,z);
		return 1;
	}
	return 0;
}

// GetNPCPos(NPC:npcid,&Float:X,&Float:Y,&Float:Z);
static cell AMX_NATIVE_CALL n_GetNPCPos( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x,y,z;
		NPC[npcid]->GetPos(&x,&y,&z);
		cell
			* p1,
			* p2,
			* p3;
		amx_GetAddr(amx, params[2], &p1);
		amx_GetAddr(amx, params[3], &p2);
		amx_GetAddr(amx, params[4], &p3);
		*p1 = amx_ftoc(x);
		*p2 = amx_ftoc(y);
		*p3 = amx_ftoc(z);
		return 1;
	}
	return 0;
}

// SetNPCFacingAngle(NPC:npcid,Float:angle);
static cell AMX_NATIVE_CALL n_SetNPCFacingAngle( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->SetAngle(amx_ctof(params[2]));
		return 1;
	}
	return 0;
}

// Float:GetNPCFacingAngle(NPC:npcid);
static cell AMX_NATIVE_CALL n_GetNPCFacingAngle( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float a = NPC[npcid]->GetAngle();
		return amx_ftoc(a);
	}
	return 0;
}
// SetNPCVelocity(NPC:npcid,Float:X,Float:Y,Float:Z);
static cell AMX_NATIVE_CALL n_SetNPCVelocity( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x = amx_ctof(params[2]);
		float y = amx_ctof(params[3]);
		float z = amx_ctof(params[4]);
		NPC[npcid]->SetVelocity(x,y,z);
		return 1;
	}
	return 0;
}

// GetNPCVelocity(NPC:npcid,&Float:X,&Float:Y,&Float:Z);
static cell AMX_NATIVE_CALL n_GetNPCVelocity( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x,y,z;
		NPC[npcid]->GetVelocity(&x,&y,&z);
		cell
			* p1,
			* p2,
			* p3;
		amx_GetAddr(amx, params[2], &p1);
		amx_GetAddr(amx, params[3], &p2);
		amx_GetAddr(amx, params[4], &p3);
		*p1 = amx_ftoc(x);
		*p2 = amx_ftoc(y);
		*p3 = amx_ftoc(z);
		return 1;
	}
	return 0;
}
// NPC_WalkTo(NPC:npcid,Float:X,Float:Y,Float:Z,is_z_map);
static cell AMX_NATIVE_CALL n_NPC_WalkTo( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x = amx_ctof(params[2]);
		float y = amx_ctof(params[3]);
		float z = amx_ctof(params[4]);
		NPC[npcid]->GoTo(x,y,z,NPC_WALKING_DISTANCE,(int)params[5]);
		NPC[npcid]->SetKeys(KEY_UP,0,KEY_WALK);
		return 1;
	}
	return 0;
}

// NPC_RunTo(NPC:npcid,Float:X,Float:Y,Float:Z,is_z_map);
static cell AMX_NATIVE_CALL n_NPC_RunTo( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x = amx_ctof(params[2]);
		float y = amx_ctof(params[3]);
		float z = amx_ctof(params[4]);
		NPC[npcid]->GoTo(x,y,z,NPC_RUNING_DISTANCE,(int)params[5]);
		NPC[npcid]->SetKeys(KEY_UP,0,0);
		return 1;
	}
	return 0;
}

// NPC_SprintTo(NPC:npcid,Float:X,Float:Y,Float:Z,is_z_map);
static cell AMX_NATIVE_CALL n_NPC_SprintTo( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x = amx_ctof(params[2]);
		float y = amx_ctof(params[3]);
		float z = amx_ctof(params[4]);
		NPC[npcid]->GoTo(x,y,z,NPC_SPRINTING_DISTANCE,(int)params[5]);
		NPC[npcid]->SetKeys(KEY_UP,0,KEY_SPRINT);
		return 1;
	}
	return 0;
}

// NPC_LookAt(NPC:npcid,Float:X,Float:Y,Float:Z);
static cell AMX_NATIVE_CALL n_NPC_LookAt( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x,y,z,tx,ty,tz;
		NPC[npcid]->GetPos(&x,&y,&z);
		z += 0.7;
		tx = amx_ctof(params[2]);
		ty = amx_ctof(params[3]);
		tz = amx_ctof(params[4]);
		// create vector
		tx -= x;
		ty -= y;
		tz -= z;
		// set data
		NPC[npcid]->SetCameraPos(x,y,z);
		NPC[npcid]->SetCameraFrontVector(tx,ty,tz);
		NPC[npcid]->SetCameraMode(53);
		int ud,lr,other;
		NPC[npcid]->GetKeys(&ud,&lr,&other);
		NPC[npcid]->SetKeys(ud,lr,0);
		return 1;
	}
	return 0;
}

// NPC_AimAt(NPC:npcid,Float:X,Float:Y,Float:Z);
static cell AMX_NATIVE_CALL n_NPC_AimAt( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x,y,z,tx,ty,tz;
		NPC[npcid]->GetPos(&x,&y,&z);
		z += 0.7;
		tx = amx_ctof(params[2]);
		ty = amx_ctof(params[3]);
		tz = amx_ctof(params[4]);
		// z angle
		float a = (atan2((ty - y),(tx - x)) * 57.2957763671875) + 270.0;
		if(a > 360.0) a -= 360.0;
		// create vector
		tx -= x;
		ty -= y;
		tz -= z;
		// z camera angle
		float z_aim = -acos(((tx *tx) + (ty * ty)) / (sqrt((tx * tx) + (ty * ty) + (tz * tz)) * sqrt((tx * tx) + (ty * ty)))) + 0.1;
		NPC[npcid]->SetCameraZAim(z_aim);
		// set data
		NPC[npcid]->SetCameraPos(x,y,z);
		NPC[npcid]->SetCameraFrontVector(tx,ty,tz);
		int ud,lr,other;
		switch(NPC[npcid]->GetState())
		{
		case NPC_STATE_ONFOOT:
			{
				NPC[npcid]->GetKeys(&ud,&lr,&other);
				NPC[npcid]->SetKeys(ud,lr,KEY_HANDBRAKE);
				break;
			}
		case NPC_STATE_DRIVER:
			{
				break;
			}
		case NPC_STATE_PASSENGER:
			{
				NPC[npcid]->GetPassangerKeys(&ud,&lr,&other);
				NPC[npcid]->SetPassangerKeys(ud,lr,KEY_HANDBRAKE);
				break;
			}
		}
		// camera mode
		switch(NPC[npcid]->GetWeapon())
		{
		case 0: break;
		// 2 hands
		case WEAPON_COLT45:
		case WEAPON_SAWEDOFF:
		case WEAPON_UZI:
		case WEAPON_TEC9:
			{
				NPC[npcid]->SetCameraMode(53);
				NPC[npcid]->SetWeaponState(2);
				break;
			}
		// 1 hand
		default:
			{
				NPC[npcid]->SetCameraMode(7);
				NPC[npcid]->SetWeaponState(2);
				// z aim
				NPC[npcid]->SetAngle(a);
				break;
			}
		}
		return 1;
	}
	return 1;
}

// NPC_ShotAt(NPC:npcid,Float:X,Float:Y,Float:Z);
static cell AMX_NATIVE_CALL n_NPC_ShotAt( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x,y,z,tx,ty,tz;
		NPC[npcid]->GetPos(&x,&y,&z);
		z += 0.7;
		tx = amx_ctof(params[2]);
		ty = amx_ctof(params[3]);
		tz = amx_ctof(params[4]);
		// z angle
		float a = (atan2((ty - y),(tx - x)) * 57.2957763671875) + 270.0;
		if(a > 360.0) a -= 360.0;
		// create vector
		tx -= x;
		ty -= y;
		tz -= z;
		// z camera angle
		float z_aim = -acos(((tx *tx) + (ty * ty)) / (sqrt((tx * tx) + (ty * ty) + (tz * tz)) * sqrt((tx * tx) + (ty * ty)))) + 0.1;
		NPC[npcid]->SetCameraZAim(z_aim);
		// set data
		NPC[npcid]->SetCameraPos(x,y,z);
		NPC[npcid]->SetCameraFrontVector(tx,ty,tz);
		// keys
		int ud,lr,other;
		switch(NPC[npcid]->GetState())
		{
		case NPC_STATE_ONFOOT:
			{
				NPC[npcid]->GetKeys(&ud,&lr,&other);
				NPC[npcid]->SetKeys(ud,lr,KEY_HANDBRAKE + KEY_FIRE);
				break;
			}
		case NPC_STATE_DRIVER:
			{
				NPC[npcid]->GetVehicleKeys(&ud,&lr,&other);
				NPC[npcid]->SetVehicleKeys(ud,lr,KEY_FIRE);
				break;
			}
		case NPC_STATE_PASSENGER:
			{
				NPC[npcid]->GetPassangerKeys(&ud,&lr,&other);
				NPC[npcid]->SetPassangerKeys(ud,lr,KEY_HANDBRAKE + KEY_FIRE);
				break;
			}
		}
		// camera mode
		switch(NPC[npcid]->GetWeapon())
		{
		case 0: break;
		// 2 hands
		case WEAPON_COLT45:
		case WEAPON_SAWEDOFF:
		case WEAPON_UZI:
		case WEAPON_TEC9:
			{
				NPC[npcid]->SetCameraMode(53);
				NPC[npcid]->SetWeaponState(WEAPONSTATE_MORE_BULLETS);
				break;
			}
		// 1 hand
		default:
			{
				NPC[npcid]->SetCameraMode(7);
				NPC[npcid]->SetWeaponState(WEAPONSTATE_MORE_BULLETS);
				// z aim
				NPC[npcid]->SetAngle(a);
				break;
			}
		}
		return 1;
	}
	return 1;
}

// SetNPCCameraPos(NPC:npcid,Float:X,Float:Y,Float:Z);
static cell AMX_NATIVE_CALL n_SetNPCCameraPos( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x = amx_ctof(params[2]);
		float y = amx_ctof(params[3]);
		float z = amx_ctof(params[4]);
		NPC[npcid]->SetCameraPos(x,y,z);
		return 1;
	}
	return 0;
}

// GetNPCCameraPos(NPC:npcid,&Float:X,&Float:Y,&Float:Z);
static cell AMX_NATIVE_CALL n_GetNPCCameraPos( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x,y,z;
		NPC[npcid]->GetCameraPos(&x,&y,&z);
		cell
			* p1,
			* p2,
			* p3;
		amx_GetAddr(amx, params[2], &p1);
		amx_GetAddr(amx, params[3], &p2);
		amx_GetAddr(amx, params[4], &p3);
		*p1 = amx_ftoc(x);
		*p2 = amx_ftoc(y);
		*p3 = amx_ftoc(z);
		return 1;
	}
	return 0;
}
// SetNPCCameraFrontVector(NPC:npcid,Float:X,Float:Y,Float:Z);
static cell AMX_NATIVE_CALL n_SetNPCCameraFrontVector( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x = amx_ctof(params[2]);
		float y = amx_ctof(params[3]);
		float z = amx_ctof(params[4]);
		NPC[npcid]->SetCameraFrontVector(x,y,z);
		return 1;
	}
	return 0;
}

// GetNPCCameraFrontVector(NPC:npcid,&Float:X,&Float:Y,&Float:Z);
static cell AMX_NATIVE_CALL n_GetNPCCameraFrontVector( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x,y,z;
		NPC[npcid]->GetCameraFrontVector(&x,&y,&z);
		cell
			* p1,
			* p2,
			* p3;
		amx_GetAddr(amx, params[2], &p1);
		amx_GetAddr(amx, params[3], &p2);
		amx_GetAddr(amx, params[4], &p3);
		*p1 = amx_ftoc(x);
		*p2 = amx_ftoc(y);
		*p3 = amx_ftoc(z);
		return 1;
	}
	return 0;
}
// SetNPCCameraMode(NPC:npcid,mode);
static cell AMX_NATIVE_CALL n_SetNPCCameraMode( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->SetCameraMode((int)params[2]);
		return 1;
	}
	return 0;
}

// GetNPCCameraMode(NPC:npcid);
static cell AMX_NATIVE_CALL n_GetNPCCameraMode( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		return NPC[npcid]->GetCameraMode();
	}
	return 0;
}
// SetNPCWeaponState(NPC:npcid,state);
static cell AMX_NATIVE_CALL n_SetNPCWeaponState( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->SetWeaponState(((int)params[2] << 6));
		return 1;
	}
	return 0;
}

// GetNPCWeaponState(NPC:npcid);
static cell AMX_NATIVE_CALL n_GetNPCWeaponState( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		return NPC[npcid]->GetWeaponState() >> 6;
	}
	return 0;
}
// SetNPCKeys(NPC:npcid,updown,leftright,keys);
static cell AMX_NATIVE_CALL n_SetNPCKeys( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		int ud = (int)params[2];
		int lr = (int)params[3];
		int other = (int)params[4];
		NPC[npcid]->SetKeys(ud,lr,other);
		return 1;
	}
	return 0;
}

// GetNPCKeys(NPC:npcid,&updown,&leftright,&keys);
static cell AMX_NATIVE_CALL n_GetNPCKeys( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		int ud,lr,other;
		NPC[npcid]->GetKeys(&ud,&lr,&other);
		cell
			* p1,
			* p2,
			* p3;
		amx_GetAddr(amx, params[2], &p1);
		amx_GetAddr(amx, params[3], &p2);
		amx_GetAddr(amx, params[4], &p3);
		*p1 = ud;
		*p2 = lr;
		*p3 = other;
		return 1;
	}
	return 0;
}

// SetNPCWeapon(NPC:npcid,weaponid);
static cell AMX_NATIVE_CALL n_SetNPCWeapon( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->SetWeapon((int)params[2]);
		return 1;
	}
	return 0;
}

// GetNPCWeapon(NPC:npcid);
static cell AMX_NATIVE_CALL n_GetNPCWeapon( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		return NPC[npcid]->GetWeapon();
	}
	return 0;
}
// SetNPCWeaponSkillLevel(NPC:npcid,weapontype,level);
static cell AMX_NATIVE_CALL n_SetNPCWeaponSkillLevel( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->SetWeaponSkillLevel((int)params[2],(int)params[3]);
		return 1;
	}
	return 0;
}

// GetNPCWeaponSkillLevel(NPC:npcid,weapontype);
static cell AMX_NATIVE_CALL n_GetNPCWeaponSkillLevel( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		return NPC[npcid]->GetWeaponSkillLevel((int)params[2]);
	}
	return 0;
}
// SetNPCHealth(NPC:npcid,Float:health);
static cell AMX_NATIVE_CALL n_SetNPCHealth( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float health = amx_ctof(params[2]);
		NPC[npcid]->SetHealth(health);
		if(health <= 0.0) NPC[npcid]->Kill(-1,0);
		return 1;
	}
	return 0;
}

// Float:GetNPCHealth(NPC:npcid);
static cell AMX_NATIVE_CALL n_GetNPCHealth( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float health = NPC[npcid]->GetHealth();
		return amx_ftoc(health);
	}
	return 0;
}
// SetNPCArmour(NPC:npcid,Float:armour);
static cell AMX_NATIVE_CALL n_SetNPCArmour( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float armour = amx_ctof(params[2]);
		NPC[npcid]->SetArmour(armour);
		return 1;
	}
	return 0;
}

// Float:GetNPCArmour(NPC:npcid);
static cell AMX_NATIVE_CALL n_GetNPCArmour( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float armour = NPC[npcid]->GetArmour();
		return amx_ftoc(armour);
	}
	return 0;
}
// SetNPCInterior(NPC:npcid,interior);
static cell AMX_NATIVE_CALL n_SetNPCInterior( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->SetInterior(params[2]);
		return 1;
	}
	return 0;
}

// GetNPCInterior(NPC:npcid);
static cell AMX_NATIVE_CALL n_GetNPCInterior( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		return NPC[npcid]->GetInterior();
	}
	return 0;
}
// SetNPCSpecialAction(NPC:npcid,interior);
static cell AMX_NATIVE_CALL n_SetNPCSpecialAction( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->SetSpecialAction(params[2]);
		return 1;
	}
	return 0;
}

// GetNPCSpecialAction(NPC:npcid);
static cell AMX_NATIVE_CALL n_GetNPCSpecialAction( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		return NPC[npcid]->GetSpecialAction();
	}
	return 0;
}
// SetNPCSkin(NPC:npcid,skin);
static cell AMX_NATIVE_CALL n_SetNPCSkin( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->SetSkin(params[2]);
		return 1;
	}
	return 0;
}

// GetNPCSkin(NPC:npcid);
static cell AMX_NATIVE_CALL n_GetNPCSkin( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		return NPC[npcid]->GetSkin();
	}
	return 0;
}
// SetNPCSurfing(NPC:npcid,Float:X,Float:Y,Float:Z);
static cell AMX_NATIVE_CALL n_SetNPCSurfing( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x = amx_ctof(params[2]);
		float y = amx_ctof(params[3]);
		float z = amx_ctof(params[4]);
		NPC[npcid]->SetSurfing(x,y,z);
		return 1;
	}
	return 0;
}

// GetNPCSurfing(NPC:npcid,&Float:X,&Float:Y,&Float:Z);
static cell AMX_NATIVE_CALL n_GetNPCSurfing( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x,y,z;
		NPC[npcid]->GetSurfing(&x,&y,&z);
		cell
			* p1,
			* p2,
			* p3;
		amx_GetAddr(amx, params[2], &p1);
		amx_GetAddr(amx, params[3], &p2);
		amx_GetAddr(amx, params[4], &p3);
		*p1 = amx_ftoc(x);
		*p2 = amx_ftoc(y);
		*p3 = amx_ftoc(z);
		return 1;
	}
	return 0;
}
// SetNPCSurfingVehicle(NPC:npcid,vehicleid);
static cell AMX_NATIVE_CALL n_SetNPCSurfingVehicle( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->SetSurfingVehicle(params[2]);
		return 1;
	}
	return 0;
}

// GetNPCSurfingVehicle(NPC:npcid);
static cell AMX_NATIVE_CALL n_GetNPCSurfingVehicle( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		return NPC[npcid]->GetSurfingVehicle();
	}
	return 0;
}

// SetNPCImpregnable(NPC:npcid,bool:istate);
static cell AMX_NATIVE_CALL n_SetNPCImpregnable( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->SetImpregnable((bool)params[2]);
		return 1;
	}
	return 0;
}

// IsNPCImpregnable(NPC:npcid);
static cell AMX_NATIVE_CALL n_IsNPCImpregnable( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		return NPC[npcid]->IsImpregnable();
	}
	return 0;
}

// KillNPC(NPC:npcid);
static cell AMX_NATIVE_CALL n_KillNPC( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->Kill(-1,0);
		return 1;
	}
	return 0;
}

// SpawnNPC(NPC:npcid);
static cell AMX_NATIVE_CALL n_SpawnNPC( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->Spawn();
		return 1;
	}
	return 0;
}

// StopNPC(NPC:npcid);
static cell AMX_NATIVE_CALL n_StopNPC( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->Stop();
		NPC[npcid]->SetKeys(0,0,0);
		return 1;
	}
	return 0;
}
// PutNPCInVehicle(NPC:npcid,vehicleid,seat);
static cell AMX_NATIVE_CALL n_PutNPCInVehicle( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->PutInVehicle((int)params[2],(int)params[3]);
		return 1;
	}
	return 0;
}
// NPC_DriveTo(NPC:npcid,Float:X,Float:Y,Float:Z,Float:speed,is_z_map);
static cell AMX_NATIVE_CALL n_NPC_DriveTo( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x = amx_ctof(params[2]);
		float y = amx_ctof(params[3]);
		float z = amx_ctof(params[4]);
		float speed = amx_ctof(params[5]);
		NPC[npcid]->DriveTo(x,y,z,speed,(int)params[6]);
		NPC[npcid]->SetVehicleKeys(0,0,0);
		return 1;
	}
	return 0;
}
// SetNPCVehiclePos(NPC:npcid,Float:X,Float:Y,Float:Z);
static cell AMX_NATIVE_CALL n_SetNPCVehiclePos( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x = amx_ctof(params[2]);
		float y = amx_ctof(params[3]);
		float z = amx_ctof(params[4]);
		NPC[npcid]->SetVehiclePos(x,y,z);
		return 1;
	}
	return 0;
}

// GetNPCVehiclePos(NPC:npcid,&Float:X,&Float:Y,&Float:Z);
static cell AMX_NATIVE_CALL n_GetNPCVehiclePos( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x,y,z;
		NPC[npcid]->GetVehiclePos(&x,&y,&z);
		cell
			* p1,
			* p2,
			* p3;
		amx_GetAddr(amx, params[2], &p1);
		amx_GetAddr(amx, params[3], &p2);
		amx_GetAddr(amx, params[4], &p3);
		*p1 = amx_ftoc(x);
		*p2 = amx_ftoc(y);
		*p3 = amx_ftoc(z);
		return 1;
	}
	return 0;
}
// SetNPCVehicleQuaternion(NPC:npcid,Float:X,Float:Y,Float:Z,Float:Scal);
static cell AMX_NATIVE_CALL n_SetNPCVehicleQuaternion( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x = amx_ctof(params[2]);
		float y = amx_ctof(params[3]);
		float z = amx_ctof(params[4]);
		float s = amx_ctof(params[5]);
		NPC[npcid]->SetVehicleQuaternion(x,y,z,s);
		return 1;
	}
	return 0;
}

// GetNPCVehicleQuaternion(NPC:npcid,&Float:X,&Float:Y,&Float:Z,&Float:Scal);
static cell AMX_NATIVE_CALL n_GetNPCVehicleQuaternion( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x,y,z,s;
		NPC[npcid]->GetVehicleQuaternion(&x,&y,&z,&s);
		cell
			* p1,
			* p2,
			* p3,
			* p4;
		amx_GetAddr(amx, params[2], &p1);
		amx_GetAddr(amx, params[3], &p2);
		amx_GetAddr(amx, params[4], &p3);
		amx_GetAddr(amx, params[5], &p4);
		*p1 = amx_ftoc(x);
		*p2 = amx_ftoc(y);
		*p3 = amx_ftoc(z);
		*p4 = amx_ftoc(s);
		return 1;
	}
	return 0;
}
// SetNPCVehicleVelocity(NPC:npcid,Float:X,Float:Y,Float:Z);
static cell AMX_NATIVE_CALL n_SetNPCVehicleVelocity( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x = amx_ctof(params[2]);
		float y = amx_ctof(params[3]);
		float z = amx_ctof(params[4]);
		NPC[npcid]->SetVehicleVelocity(x,y,z);
		return 1;
	}
	return 0;
}

// GetNPCVehicleVelocity(NPC:npcid,&Float:X,&Float:Y,&Float:Z);
static cell AMX_NATIVE_CALL n_GetNPCVehicleVelocity( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		float x,y,z;
		NPC[npcid]->GetVehicleVelocity(&x,&y,&z);
		cell
			* p1,
			* p2,
			* p3;
		amx_GetAddr(amx, params[2], &p1);
		amx_GetAddr(amx, params[3], &p2);
		amx_GetAddr(amx, params[4], &p3);
		*p1 = amx_ftoc(x);
		*p2 = amx_ftoc(y);
		*p3 = amx_ftoc(z);
		return 1;
	}
	return 0;
}
// SetNPCVehicleKeys(NPC:npcid,updown,leftright,keys);
static cell AMX_NATIVE_CALL n_SetNPCVehicleKeys( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		int ud = (int)params[2];
		int lr = (int)params[3];
		int other = (int)params[4];
		NPC[npcid]->SetVehicleKeys(ud,lr,other);
		return 1;
	}
	return 0;
}

// GetNPCVehicleKeys(NPC:npcid,&updown,&leftright,&keys);
static cell AMX_NATIVE_CALL n_GetNPCVehicleKeys( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		int ud,lr,other;
		NPC[npcid]->GetVehicleKeys(&ud,&lr,&other);
		cell
			* p1,
			* p2,
			* p3;
		amx_GetAddr(amx, params[2], &p1);
		amx_GetAddr(amx, params[3], &p2);
		amx_GetAddr(amx, params[4], &p3);
		*p1 = ud;
		*p2 = lr;
		*p3 = other;
		return 1;
	}
	return 0;
}
// SetNPCVehicleWeapon(NPC:npcid,weaponid);
static cell AMX_NATIVE_CALL n_SetNPCVehicleWeapon( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->SetVehicleWeapon(params[2]);
		return 1;
	}
	return 0;
}

// GetNPCVehicleWeapon(NPC:npcid);
static cell AMX_NATIVE_CALL n_GetNPCVehicleWeapon( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		return NPC[npcid]->GetVehicleWeapon();
	}
	return 0;
}
// SetNPCVehicleSiren(NPC:npcid,state);
static cell AMX_NATIVE_CALL n_SetNPCVehicleSiren( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->SetVehicleSiren(params[2]);
		return 1;
	}
	return 0;
}

// GetNPCVehicleSiren(NPC:npcid);
static cell AMX_NATIVE_CALL n_GetNPCVehicleSiren( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		return NPC[npcid]->GetVehicleSiren();
	}
	return 0;
}
// SetNPCPassangerDriveBy(NPC:npcid,weaponid);
static cell AMX_NATIVE_CALL n_SetNPCPassangerDriveBy( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->SetPassangerDriveBy(params[2]);
		return 1;
	}
	return 0;
}

// GetNPCPassangerDriveBy(NPC:npcid);
static cell AMX_NATIVE_CALL n_GetNPCPassangerDriveBy( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		return NPC[npcid]->GetPassangerDriveBy();
	}
	return 0;
}
// SetNPCPassangerWeapon(NPC:npcid,weaponid);
static cell AMX_NATIVE_CALL n_SetNPCPassangerWeapon( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->SetPassangerWeapon(params[2]);
		return 1;
	}
	return 0;
}

// GetNPCPassangerWeapon(NPC:npcid);
static cell AMX_NATIVE_CALL n_GetNPCPassangerWeapon( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		return NPC[npcid]->GetPassangerWeapon();
	}
	return 0;
}
// SetNPCPassangerKeys(NPC:npcid,updown,leftright,keys);
static cell AMX_NATIVE_CALL n_SetNPCPassangerKeys( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		int ud = (int)params[2];
		int lr = (int)params[3];
		int other = (int)params[4];
		NPC[npcid]->SetPassangerKeys(ud,lr,other);
		return 1;
	}
	return 0;
}

// GetNPCPassangerKeys(NPC:npcid,&updown,&leftright,&keys);
static cell AMX_NATIVE_CALL n_GetNPCPassangerKeys( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		int ud,lr,other;
		NPC[npcid]->GetPassangerKeys(&ud,&lr,&other);
		cell
			* p1,
			* p2,
			* p3;
		amx_GetAddr(amx, params[2], &p1);
		amx_GetAddr(amx, params[3], &p2);
		amx_GetAddr(amx, params[4], &p3);
		*p1 = ud;
		*p2 = lr;
		*p3 = other;
		return 1;
	}
	return 0;
}
// SetWeaponDamageForNPC(weaponid,Float:damage);
static cell AMX_NATIVE_CALL n_SetWeaponDamageForNPC( AMX* amx, cell* params )
{
	int weaponid = (int)params[1];
	WeaponsDamage[weaponid] = amx_ctof(params[2]);
	return 1;	
}
// SetWeaponReloadTimeForNPC(weaponid,mstime);
static cell AMX_NATIVE_CALL n_SetWeaponReloadTimeForNPC( AMX* amx, cell* params )
{
	int weaponid = (int)params[1];
	WeaponsReloadTime[weaponid] = (int)params[2];
	return 1;	
}
// StartRecordingPlayback(NPC:npcid,name[]);
static cell AMX_NATIVE_CALL n_StartRecordingPlayback( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		char* temp;
		amx_StrParam(amx, params[2], temp);
		return NPC[npcid]->StartRecordingPlayback(temp);
	}
	return 0;	
}
// PauseRecordingPlayback(NPC:npcid);
static cell AMX_NATIVE_CALL n_PauseRecordingPlayback( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->PauseRecordingPlayback();
		return 1;
	}
	return 0;	
}
// ContinueRecordingPlayback(NPC:npcid);
static cell AMX_NATIVE_CALL n_ContinueRecordingPlayback( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->ContinueRecordingPlayback();
		return 1;
	}
	return 0;	
}
// StopRecordingPlayback(NPC:npcid);
static cell AMX_NATIVE_CALL n_StopRecordingPlayback( AMX* amx, cell* params )
{
	int npcid = (int)params[1];
	if(NPC[npcid])
	{
		NPC[npcid]->StopRecordingPlayback(NPC_RECORD_END_REASON_STOP);
		return 1;
	}
	return 0;	
}
// Node:OpenNode(name[]);
static cell AMX_NATIVE_CALL n_OpenNode( AMX* amx, cell* params )
{
	for(int i = 0;i < MAX_NODES;i++)
	{
		if(Nodes[i]) continue;
		char* temp;
		amx_StrParam(amx, params[1], temp);

		Nodes[i] = new CNode(temp);
		return i;
	}
	return 0;	
}
// CloseNode(Node:nodeid);
static cell AMX_NATIVE_CALL n_CloseNode( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		delete Nodes[nodeid];
		Nodes[nodeid] = 0;
		return 1;
	}
	return 0;
}
// GetNodeHeader(Node:nodeid,&nodes,&vehicle_nodes,&ped_nodes,&navi_nodes);
static cell AMX_NATIVE_CALL n_GetNodeHeader( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		int d1 = 0,
			d2 = 0,
			d3 = 0,
			d4 = 0;
		Nodes[nodeid]->GetInfo(&d1,&d2,&d3,&d4);
		//
		cell
			* p1,
			* p2,
			* p3,
			* p4;
		amx_GetAddr(amx, params[2], &p1);
		amx_GetAddr(amx, params[3], &p2);
		amx_GetAddr(amx, params[4], &p3);
		amx_GetAddr(amx, params[5], &p4);
		//
		*p1 = d1;
		*p2 = d2;
		*p3 = d3;
		*p4 = d4;
		return 1;
	}
	return 0;
}
// SetNodePoint(Node:nodeid,node_type,pointid);
static cell AMX_NATIVE_CALL n_SetNodePoint( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		Nodes[nodeid]->SetPoint((int)params[2]);
		return 1;
	}
	return 0;
}
// GetNodePoint(Node:nodeid);
static cell AMX_NATIVE_CALL n_GetNodePoint( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		return Nodes[nodeid]->GetPointId();
	}
	return 0;
}
// GetNodePointPos(Node:nodeid,&Float:X,&Float:Y,&Float:Z);
static cell AMX_NATIVE_CALL n_GetNodePointPos( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		float x,y,z;
		Nodes[nodeid]->GetPos(&x,&y,&z);

		cell
			* p1,
			* p2,
			* p3;
		amx_GetAddr(amx, params[2], &p1);
		amx_GetAddr(amx, params[3], &p2);
		amx_GetAddr(amx, params[4], &p3);

		*p1 = amx_ftoc(x);
		*p2 = amx_ftoc(y);
		*p3 = amx_ftoc(z);
		return 1;
	}
	return 0;
}
// GetNodePointLinkId(Node:nodeid);
static cell AMX_NATIVE_CALL n_GetNodePointLinkId( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		return Nodes[nodeid]->GetLinkId();
	}
	return 0;
}
// GetNodePointAreaId(Node:nodeid);
static cell AMX_NATIVE_CALL n_GetNodePointAreaId( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		return Nodes[nodeid]->GetAreaId();
	}
	return 0;
}
// GetNodePointWidth(Node:nodeid);
static cell AMX_NATIVE_CALL n_GetNodePointWidth( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		return Nodes[nodeid]->GetPathWidth();
	}
	return 0;
}
// GetNodePointLinkCount(Node:nodeid);
static cell AMX_NATIVE_CALL n_GetNodePointLinkCount( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		return Nodes[nodeid]->GetLinkCount();
	}
	return 0;
}
// GetNodePointTrafficLevel(Node:nodeid);
static cell AMX_NATIVE_CALL n_GetNodePointTrafficLevel( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		return Nodes[nodeid]->GetTrafficLevel();
	}
	return 0;
}
// IsNodePointRoadBlock(Node:nodeid);
static cell AMX_NATIVE_CALL n_IsNodePointRoadBlock( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		return Nodes[nodeid]->IsRoadBlock();
	}
	return 0;
}
// IsNodePointBoats(Node:nodeid);
static cell AMX_NATIVE_CALL n_IsNodePointBoats( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		return Nodes[nodeid]->IsBoats();
	}
	return 0;
}
// IsNodePointEmergency(Node:nodeid);
static cell AMX_NATIVE_CALL n_IsNodePointEmergency( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		return Nodes[nodeid]->IsEmergency();
	}
	return 0;
}
// IsNodePointNotHighway(Node:nodeid);
static cell AMX_NATIVE_CALL n_IsNodePointNotHighway( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		return Nodes[nodeid]->IsNotHighway();
	}
	return 0;
}
// IsNodePointSpawn(Node:nodeid);
static cell AMX_NATIVE_CALL n_IsNodePointSpawn( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		return Nodes[nodeid]->IsSpawn();
	}
	return 0;
}
// IsNodePointRoadBlock1(Node:nodeid);
static cell AMX_NATIVE_CALL n_IsNodePointRoadBlock1( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		return Nodes[nodeid]->IsRoadBlock1();
	}
	return 0;
}
// IsNodePointParking(Node:nodeid);
static cell AMX_NATIVE_CALL n_IsNodePointParking( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		return Nodes[nodeid]->IsParking();
	}
	return 0;
}
// IsNodePointRoadBlock2(Node:nodeid);
static cell AMX_NATIVE_CALL n_IsNodePointRoadBlock2( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		return Nodes[nodeid]->IsRoadBlock2();
	}
	return 0;
}
// GetNodePointType(Node:nodeid);
static cell AMX_NATIVE_CALL n_GetNodePointType( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		return Nodes[nodeid]->GetNodeType();
	}
	return 0;
}
// SetNodeLink(Node:nodeid,linkid);
static cell AMX_NATIVE_CALL n_SetNodeLink( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		Nodes[nodeid]->SetLink((int)params[2]);
		return 1;
	}
	return 0;
}
// GetNodeLinkAreaId(Node:nodeid);
static cell AMX_NATIVE_CALL n_GetNodeLinkAreaId( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		return Nodes[nodeid]->GetLinkAreaId();
	}
	return 0;
}
// GetNodeLinkNodeId(Node:nodeid,&type);
static cell AMX_NATIVE_CALL n_GetNodeLinkNodeId( AMX* amx, cell* params )
{
	int nodeid = (int)params[1];
	if(Nodes[nodeid])
	{
		return Nodes[nodeid]->GetLinkNodeId();
	}
	return 0;
}
// ToogleVisualDeath(tstate);
static cell AMX_NATIVE_CALL n_ToogleVisualDeath( AMX* amx, cell* params )
{
	VisualDeath = (int)params[1];
	return 1;
}
// DisableJoinPartLogging();
static cell AMX_NATIVE_CALL n_DisableJoinPartLogging( AMX* amx, cell* params )
{
	// [join]
	#ifdef WIN32
		DWORD oldpt;
		VirtualProtect((LPVOID)LoggingJoinPointer,5,PAGE_EXECUTE_READWRITE,&oldpt);
		VirtualProtect((LPVOID)LoggingPartPointer,5,PAGE_EXECUTE_READWRITE,&oldpt);
	#else
		mprotect((void*)(LoggingJoinPointer), 5, PROT_WRITE | PROT_READ | PROT_EXEC);
		mprotect((void*)(LoggingPartPointer), 5, PROT_WRITE | PROT_READ | PROT_EXEC);
	#endif
	for(int i = 0;i < 5;i++) 
	{
		*(BYTE*)(LoggingJoinPointer + i) = 0x90;
		*(BYTE*)(LoggingPartPointer + i) = 0x90;
	}
	return 1;
}
// ZMap_Init(mapname[]);
static cell AMX_NATIVE_CALL n_ZMap_Init( AMX* amx, cell* params )
{
	if(!ZMap)
	{
		char* temp;
		amx_StrParam(amx, params[1], temp);

		ZMap = new CZMap(temp);
		return 1;
	}
	return 0;	
}
// Float:ZMap_GetZForCoords(Float:X,Float:Y);
static cell AMX_NATIVE_CALL n_ZMap_GetZForCoords( AMX* amx, cell* params )
{
	if(ZMap)
	{
		float z = ZMap->GetZForCoords(amx_ctof(params[1]),amx_ctof(params[2]));
		return amx_ftoc(z);
	}
	return 0;	
}
// FindLastFreeSlot();
static cell AMX_NATIVE_CALL n_FindLastFreeSlot( AMX* amx, cell* params )
{
	DWORD samp = *(DWORD*)(CSampPointer);
	DWORD players = *(DWORD*)(samp + C_SAMP_PLAYERS_OFFSET);
	for(int i = (MAX_PLAYERS - 1);i > 0;i--)
	{
		if(!*(DWORD*)(players + (i * 4) + C_PLAYERS_PLAYER_OFFSET)) return i;
	}
	return INVALID_PLAYER_ID;	
}
// ConvertRollToGrad(Float:roll);
static cell AMX_NATIVE_CALL n_ConvertRollToGrad( AMX* amx, cell* params )
{
	float roll = amx_ctof(params[1]);
	float res = Roll2Grad(roll);
	return amx_ftoc(res);
}
// ConvertGradToRoll(Float:grad);
static cell AMX_NATIVE_CALL n_ConvertGradToRoll( AMX* amx, cell* params )
{
	float grad = amx_ctof(params[1]);
	float res = Grad2Roll(grad);
	return amx_ftoc(res);
}

AMX_NATIVE_INFO Natives[ ] =
{
	// core
	{ "CreateNPC",					n_CreateNPC},
	{ "DestroyNPC",					n_DestroyNPC},
	{ "IsValidNPC",					n_IsValidNPC},
	{ "KillNPC",					n_KillNPC},
	{ "SpawnNPC",					n_SpawnNPC},
	{ "StopNPC",					n_StopNPC},
	{ "GetNPCState",				n_GetNPCState},
	{ "ToogleVisualDeath",			n_ToogleVisualDeath},
	{ "DisableJoinPartLogging",		n_DisableJoinPartLogging},
	// controls foot 
	{ "SetNPCPos",					n_SetNPCPos},
	{ "GetNPCPos",					n_GetNPCPos},
	{ "SetNPCFacingAngle",			n_SetNPCFacingAngle},
	{ "GetNPCFacingAngle",			n_GetNPCFacingAngle},
	{ "SetNPCVelocity",				n_SetNPCVelocity},
	{ "GetNPCVelocity",				n_GetNPCVelocity},
	{ "NPC_WalkTo",					n_NPC_WalkTo},
	{ "NPC_RunTo",					n_NPC_RunTo},
	{ "NPC_SprintTo",				n_NPC_SprintTo},
	{ "NPC_LookAt",					n_NPC_LookAt},
	{ "NPC_AimAt",					n_NPC_AimAt},
	{ "NPC_ShotAt",					n_NPC_ShotAt},
	{ "SetNPCCameraPos",			n_SetNPCCameraPos},
	{ "GetNPCCameraPos",			n_GetNPCCameraPos},
	{ "SetNPCCameraFrontVector",	n_SetNPCCameraFrontVector},
	{ "GetNPCCameraFrontVector",	n_GetNPCCameraFrontVector},
	{ "SetNPCCameraMode",			n_SetNPCCameraMode},
	{ "GetNPCCameraMode",			n_GetNPCCameraMode},
	{ "SetNPCWeaponState",			n_SetNPCWeaponState},
	{ "GetNPCWeaponState",			n_GetNPCWeaponState},
	{ "SetNPCKeys",					n_SetNPCKeys},
	{ "GetNPCKeys",					n_GetNPCKeys},
	{ "SetNPCWeapon",				n_SetNPCWeapon},
	{ "GetNPCWeapon",				n_GetNPCWeapon},
	{ "SetNPCWeaponSkillLevel",		n_SetNPCWeaponSkillLevel},
	{ "GetNPCWeaponSkillLevel",		n_GetNPCWeaponSkillLevel},
	{ "SetNPCHealth",				n_SetNPCHealth},
	{ "GetNPCHealth",				n_GetNPCHealth},
	{ "SetNPCArmour",				n_SetNPCArmour},
	{ "GetNPCArmour",				n_GetNPCArmour},
	{ "SetNPCInterior",				n_SetNPCInterior},
	{ "GetNPCInterior",				n_GetNPCInterior},
	{ "SetNPCSpecialAction",		n_SetNPCSpecialAction},
	{ "GetNPCSpecialAction",		n_GetNPCSpecialAction},
	{ "SetNPCSkin",					n_SetNPCSkin},
	{ "GetNPCSkin",					n_GetNPCSkin},
	{ "SetNPCSurfing",				n_SetNPCSurfing},
	{ "GetNPCSurfing",				n_GetNPCSurfing},
	{ "SetNPCSurfingVehicle",		n_SetNPCSurfingVehicle},
	{ "GetNPCSurfingVehicle",		n_GetNPCSurfingVehicle},
	{ "SetNPCImpregnable",			n_SetNPCImpregnable},
	{ "IsNPCImpregnable",			n_IsNPCImpregnable},
	// controls vehicle
	{ "PutNPCInVehicle",			n_PutNPCInVehicle},
	{ "NPC_DriveTo",				n_NPC_DriveTo},	
	{ "SetNPCVehiclePos",			n_SetNPCVehiclePos},
	{ "GetNPCVehiclePos",			n_GetNPCVehiclePos},
	{ "SetNPCVehicleQuaternion",	n_SetNPCVehicleQuaternion},
	{ "GetNPCVehicleQuaternion",	n_GetNPCVehicleQuaternion},
	{ "SetNPCVehicleVelocity",		n_SetNPCVehicleVelocity},
	{ "GetNPCVehicleVelocity",		n_GetNPCVehicleVelocity},
	{ "SetNPCVehicleKeys",			n_SetNPCVehicleKeys},
	{ "GetNPCVehicleKeys",			n_GetNPCVehicleKeys},
	{ "SetNPCVehicleWeapon",		n_SetNPCVehicleWeapon},
	{ "GetNPCVehicleWeapon",		n_GetNPCVehicleWeapon},
	{ "SetNPCVehicleSiren",			n_SetNPCVehicleSiren},
	{ "GetNPCVehicleSiren",			n_GetNPCVehicleSiren},
	// controls passanger
	{ "SetNPCPassangerDriveBy",		n_SetNPCPassangerDriveBy},
	{ "GetNPCPassangerDriveBy",		n_GetNPCPassangerDriveBy},
	{ "SetNPCPassangerWeapon",		n_SetNPCPassangerWeapon},
	{ "GetNPCPassangerWeapon",		n_GetNPCPassangerWeapon},
	{ "SetNPCPassangerKeys",		n_SetNPCPassangerKeys},
	{ "GetNPCPassangerKeys",		n_GetNPCPassangerKeys},
	// weapons damage
	{ "SetWeaponDamageForNPC",		n_SetWeaponDamageForNPC},
	{ "SetWeaponReloadTimeForNPC",	n_SetWeaponReloadTimeForNPC},
	// playbacks
	{ "StartRecordingPlayback",		n_StartRecordingPlayback},
	{ "PauseRecordingPlayback",		n_PauseRecordingPlayback},
	{ "ContinueRecordingPlayback",	n_ContinueRecordingPlayback},
	{ "StopRecordingPlayback",		n_StopRecordingPlayback},
	// nodes
	{ "OpenNode",					n_OpenNode},
	{ "CloseNode",					n_CloseNode},
	{ "GetNodeHeader",				n_GetNodeHeader},
	{ "SetNodePoint",				n_SetNodePoint},
	{ "GetNodePoint",				n_GetNodePoint},
	{ "GetNodePointPos",			n_GetNodePointPos},
	{ "GetNodePointLinkId",			n_GetNodePointLinkId},
	{ "GetNodePointLinkCount",		n_GetNodePointLinkCount},
	{ "GetNodePointAreaId",			n_GetNodePointAreaId},
	{ "GetNodePointWidth",			n_GetNodePointWidth},
	{ "GetNodePointType",			n_GetNodePointType},
	{ "SetNodeLink",				n_SetNodeLink},
	{ "GetNodeLinkAreaId",			n_GetNodeLinkAreaId},
	{ "GetNodeLinkNodeId",			n_GetNodeLinkNodeId},
	{ "GetNodePointTrafficLevel",	n_GetNodePointTrafficLevel},
	{ "IsNodePointRoadBlock",		n_IsNodePointRoadBlock},
	{ "IsNodePointBoats",			n_IsNodePointBoats},
	{ "IsNodePointEmergency",		n_IsNodePointEmergency},
	{ "IsNodePointNotHighway",		n_IsNodePointNotHighway},
	{ "IsNodePointSpawn",			n_IsNodePointSpawn},
	{ "IsNodePointRoadBlock1",		n_IsNodePointRoadBlock1},
	{ "IsNodePointParking",			n_IsNodePointParking},
	{ "IsNodePointRoadBlock2",		n_IsNodePointRoadBlock2},
	// zmap
	{ "ZMap_Init",					n_ZMap_Init},
	{ "ZMap_GetZForCoords",			n_ZMap_GetZForCoords},
	{ "FindLastFreeSlot",			n_FindLastFreeSlot},
	// Convert
	{ "ConvertRollToGrad",			n_ConvertRollToGrad},
	{ "ConvertGradToRoll",			n_ConvertGradToRoll},
	{ 0,							0 }
};

void NativesOnAMXLoad(AMX* amx)
{
	amx_Register(amx, Natives, -1 );
}
